package yt.demo.appcoresystem.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yt.demo.appcommondb.base.BaseService;
import yt.demo.appcommondb.dto.SplitPageDTO;
import yt.demo.appcommondb.vo.ConditionVO;
import yt.demo.appcommondb.vo.PageVO;
import yt.demo.appcommontools.utils.AssertUtils;
import yt.demo.appcommontools.utils.SaltUtils;
import yt.demo.appcoresystem.entity.SystemUser;
import yt.demo.appcoresystem.entity.SystemUserRole;
import yt.demo.appcoresystem.mapper.SystemUserMapper;
import yt.demo.appcoresystem.service.ISystemDeptService;
import yt.demo.appcoresystem.service.ISystemUserDeptService;
import yt.demo.appcoresystem.service.ISystemUserRoleService;
import yt.demo.appcoresystem.service.ISystemUserService;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class SystemUserService extends BaseService<SystemUser, SystemUserMapper> implements ISystemUserService {

    ISystemUserDeptService userDeptService;
    ISystemUserRoleService userRoleService;
    ISystemDeptService deptService;
    SystemMenuService menuService;

    @Autowired
    public SystemUserService(SystemUserMapper mapper, ISystemUserDeptService userDeptService,
                             ISystemUserRoleService userRoleService, ISystemDeptService deptService, SystemMenuService menuService) {
        super(mapper, SystemUser.class);
        this.userDeptService = userDeptService;
        this.userRoleService = userRoleService;
        this.deptService = deptService;
        this.menuService = menuService;
    }

    @Override
    public PageVO<SystemUser> getCusPageList(SplitPageDTO dto, SystemUser params) {
        PageVO<SystemUser> pageList = getPageList(dto, params, w -> {
            w.orderByDesc(SystemUser::getId);
        }, null);
        List<Long> userIds = pageList.getList().stream().map(SystemUser::getId).toList();
        this.userDeptService.belongsToDept(userIds, pageList.getList());
        this.userRoleService.belongsToRole(userIds, pageList.getList());
        return pageList;
    }

    @Override
    public List<ConditionVO<SystemUser, ?>> whereConditions(SystemUser params) {
        List<ConditionVO<SystemUser, ?>> conditions = new ArrayList<>();
        if (StrUtil.isNotEmpty(params.getUsername())) {
            conditions.add(ConditionVO.createCondition(SystemUser::getUsername, "like", params.getUsername()));
        }
        if (StrUtil.isNotEmpty(params.getPhone())) {
            conditions.add(ConditionVO.createCondition(SystemUser::getPhone, "like", params.getPhone()));
        }
        if (ObjectUtil.isNotNull(params.getStatus())) {
            conditions.add(ConditionVO.createCondition(SystemUser::getStatus, "eq", params.getStatus()));
        }
        if (ObjectUtil.isNotNull(params.getDeptId())) {
            List<Long> userIds = userDeptService.deptToUserIds(deptService.getSupDeptIds(params.getDeptId()));
            conditions.add(
                    ConditionVO.createCondition(SystemUser::getId, "in",
                            userIds.isEmpty() ? List.of(-1L) : userIds
                    )
            );
        }
        return conditions;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SystemUser create(SystemUser user) {
        AssertUtils.isTrue(isUsernameExist(user.getUsername(), null), "用户名已存在！");
        user.setSalt(SaltUtils.getSalt(4));
        if (user.getPassword() == null) {
            user.setPassword("123456");
        }
        user.setPassword(encryptPassword(user.getPassword(), user.getSalt()));
        AssertUtils.isLeZero(mapper.insert(user), "创建失败");
        if (user.getDeptIds() != null) {
            this.userDeptService.syncDept(user.getId(), user.getDeptIds());
        }
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SystemUser update(SystemUser user) {
        AssertUtils.isTrue(isUsernameExist(user.getUsername(), user.getId()), "手机号码已存在！");
        if (user.getPassword() != null) {
            user.setSalt(SaltUtils.getSalt(4));
            user.setPassword(encryptPassword(user.getPassword(), user.getSalt()));
        }
        AssertUtils.isLeZero(mapper.updateById(user), "更新用户失败！");
        if (user.getDeptIds() != null) {
            this.userDeptService.syncDept(user.getId(), user.getDeptIds());
        }
        if (user.getRoleIds() != null) {
            this.userRoleService.syncRole(user.getId(), user.getRoleIds());
        }
        return user;
    }

    @Override
    public SystemUser getUsernameInfo(String username) {
        LambdaQueryWrapper<SystemUser> wrapper = new LambdaQueryWrapper<SystemUser>().eq(SystemUser::getUsername, username);
        return mapper.selectOne(wrapper);
    }

    @Override
    public List<String> getPermissionList(Long userId) {
        return this.menuService.getUserRoleIdsRoutes(userId);
    }

    public Boolean isUsernameExist(String phone, Long userId) {
        LambdaQueryWrapper<SystemUser> wrapper = new LambdaQueryWrapper<SystemUser>().eq(SystemUser::getUsername, phone);
        if (userId != null) {
            wrapper.ne(SystemUser::getId, userId);
        }
        return mapper.selectCount(wrapper) > 0;
    }

    // 加密密码
    public String encryptPassword(String password, String salt) {
        return SecureUtil.md5(SecureUtil.md5(password) + salt);
    }

}
